using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using ns18;
using ns20;

namespace Newtonsoft.Json
{
	public abstract class JsonReader : IDisposable
	{
		protected internal enum State
		{
			Start,
			Complete,
			Property,
			ObjectStart,
			Object,
			ArrayStart,
			Array,
			Closed,
			PostValue,
			ConstructorStart,
			Constructor,
			Error,
			Finished
		}

		private JsonToken jsonToken_0;

		private object object_0;

		internal char char_0;

		internal State state_0;

		internal Enum14 enum14_0;

		private Struct25 struct25_0;

		private CultureInfo cultureInfo_0;

		private DateTimeZoneHandling dateTimeZoneHandling_0;

		private int? nullable_0;

		private bool bool_0;

		internal DateParseHandling dateParseHandling_0;

		internal FloatParseHandling floatParseHandling_0;

		private readonly List<Struct25> list_0;

		[CompilerGenerated]
		private bool bool_1;

		protected State CurrentState => state_0;

		public bool CloseInput
		{
			[CompilerGenerated]
			get
			{
				return bool_1;
			}
			[CompilerGenerated]
			set
			{
				bool_1 = value;
			}
		}

		public virtual char Char_0
		{
			get
			{
				return char_0;
			}
			protected internal set
			{
				char_0 = value;
			}
		}

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return dateTimeZoneHandling_0;
			}
			set
			{
				dateTimeZoneHandling_0 = value;
			}
		}

		public DateParseHandling DateParseHandling
		{
			get
			{
				return dateParseHandling_0;
			}
			set
			{
				dateParseHandling_0 = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return floatParseHandling_0;
			}
			set
			{
				floatParseHandling_0 = value;
			}
		}

		public int? MaxDepth
		{
			get
			{
				return nullable_0;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				nullable_0 = value;
			}
		}

		public virtual JsonToken JsonToken_0 => jsonToken_0;

		public virtual object Object_0 => object_0;

		public virtual Type Type_0
		{
			get
			{
				if (object_0 == null)
				{
					return null;
				}
				return object_0.GetType();
			}
		}

		public virtual int Int32_0
		{
			get
			{
				int count = list_0.Count;
				if (!smethod_1(JsonToken_0) && struct25_0.enum12_0 != 0)
				{
					return count + 1;
				}
				return count;
			}
		}

		public virtual string String_0
		{
			get
			{
				if (struct25_0.enum12_0 == Enum12.None)
				{
					return string.Empty;
				}
				IEnumerable<Struct25> ienumerable_ = ((state_0 == State.ArrayStart || state_0 == State.ConstructorStart || state_0 == State.ObjectStart) ? list_0 : list_0.Concat(new Struct25[1] { struct25_0 }));
				return Struct25.smethod_1(ienumerable_);
			}
		}

		public CultureInfo Culture
		{
			get
			{
				return cultureInfo_0 ?? CultureInfo.InvariantCulture;
			}
			set
			{
				cultureInfo_0 = value;
			}
		}

		internal Struct25 method_0(int int_0)
		{
			if (int_0 < list_0.Count)
			{
				return list_0[int_0];
			}
			return struct25_0;
		}

		protected JsonReader()
		{
			state_0 = State.Start;
			list_0 = new List<Struct25>(4);
			dateTimeZoneHandling_0 = DateTimeZoneHandling.RoundtripKind;
			dateParseHandling_0 = DateParseHandling.DateTime;
			floatParseHandling_0 = FloatParseHandling.Double;
			CloseInput = true;
		}

		private void method_1(Enum12 enum12_0)
		{
			method_11();
			if (struct25_0.enum12_0 == Enum12.None)
			{
				struct25_0 = new Struct25(enum12_0);
				return;
			}
			list_0.Add(struct25_0);
			struct25_0 = new Struct25(enum12_0);
			if (!nullable_0.HasValue || !(Int32_0 + 1 > nullable_0) || bool_0)
			{
				return;
			}
			bool_0 = true;
			throw JsonReaderException.smethod_1(this, "The reader's MaxDepth of {0} has been exceeded.".smethod_0(CultureInfo.InvariantCulture, nullable_0));
		}

		private Enum12 method_2()
		{
			Struct25 @struct;
			if (list_0.Count > 0)
			{
				@struct = struct25_0;
				struct25_0 = list_0[list_0.Count - 1];
				list_0.RemoveAt(list_0.Count - 1);
			}
			else
			{
				@struct = struct25_0;
				struct25_0 = default(Struct25);
			}
			if (nullable_0.HasValue && Int32_0 <= nullable_0)
			{
				bool_0 = false;
			}
			return @struct.enum12_0;
		}

		private Enum12 method_3()
		{
			return struct25_0.enum12_0;
		}

		public abstract bool Read();

		public abstract int? ReadAsInt32();

		public abstract string ReadAsString();

		public abstract byte[] ReadAsBytes();

		public abstract decimal? ReadAsDecimal();

		public abstract DateTime? ReadAsDateTime();

		public abstract DateTimeOffset? ReadAsDateTimeOffset();

		internal virtual bool Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E()
		{
			throw new NotImplementedException();
		}

		internal DateTimeOffset? method_4()
		{
			enum14_0 = Enum14.ReadAsDateTimeOffset;
			while (Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E())
			{
				JsonToken jsonToken = JsonToken_0;
				switch (jsonToken)
				{
				case JsonToken.Comment:
					break;
				case JsonToken.Date:
					if (Object_0 is DateTime)
					{
						SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Object_0));
					}
					return (DateTimeOffset)Object_0;
				case JsonToken.Null:
					return null;
				case JsonToken.String:
				{
					string text = (string)Object_0;
					if (string.IsNullOrEmpty(text))
					{
						SetToken(JsonToken.Null);
						return null;
					}
					if (DateTimeOffset.TryParse(text, Culture, DateTimeStyles.RoundtripKind, out var result))
					{
						SetToken(JsonToken.Date, result);
						return result;
					}
					throw JsonReaderException.smethod_1(this, "Could not convert string to DateTimeOffset: {0}.".smethod_0(CultureInfo.InvariantCulture, Object_0));
				}
				default:
					throw JsonReaderException.smethod_1(this, "Error reading date. Unexpected token: {0}.".smethod_0(CultureInfo.InvariantCulture, jsonToken));
				case JsonToken.EndArray:
					return null;
				}
			}
			SetToken(JsonToken.None);
			return null;
		}

		internal byte[] method_5()
		{
			enum14_0 = Enum14.ReadAsBytes;
			JsonToken jsonToken;
			do
			{
				if (Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E())
				{
					jsonToken = JsonToken_0;
					continue;
				}
				SetToken(JsonToken.None);
				return null;
			}
			while (jsonToken == JsonToken.Comment);
			if (method_10())
			{
				byte[] array = ReadAsBytes();
				Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E();
				SetToken(JsonToken.Bytes, array);
				return array;
			}
			switch (jsonToken)
			{
			case JsonToken.String:
			{
				string text = (string)Object_0;
				byte[] array3 = ((text.Length == 0) ? new byte[0] : Convert.FromBase64String(text));
				SetToken(JsonToken.Bytes, array3);
				return array3;
			}
			case JsonToken.Null:
				return null;
			case JsonToken.Bytes:
				return (byte[])Object_0;
			case JsonToken.StartArray:
			{
				List<byte> list = new List<byte>();
				while (Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E())
				{
					jsonToken = JsonToken_0;
					switch (jsonToken)
					{
					case JsonToken.Integer:
						list.Add(Convert.ToByte(Object_0, CultureInfo.InvariantCulture));
						break;
					case JsonToken.Comment:
						break;
					case JsonToken.EndArray:
					{
						byte[] array2 = list.ToArray();
						SetToken(JsonToken.Bytes, array2);
						return array2;
					}
					default:
						throw JsonReaderException.smethod_1(this, "Unexpected token when reading bytes: {0}.".smethod_0(CultureInfo.InvariantCulture, jsonToken));
					}
				}
				throw JsonReaderException.smethod_1(this, "Unexpected end when reading bytes.");
			}
			default:
				throw JsonReaderException.smethod_1(this, "Error reading bytes. Unexpected token: {0}.".smethod_0(CultureInfo.InvariantCulture, jsonToken));
			case JsonToken.EndArray:
				return null;
			}
		}

		internal decimal? method_6()
		{
			enum14_0 = Enum14.ReadAsDecimal;
			while (Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E())
			{
				JsonToken jsonToken = JsonToken_0;
				switch (jsonToken)
				{
				case JsonToken.Comment:
					break;
				case JsonToken.Null:
					return null;
				case JsonToken.String:
				{
					string text = (string)Object_0;
					if (string.IsNullOrEmpty(text))
					{
						SetToken(JsonToken.Null);
						return null;
					}
					if (decimal.TryParse(text, NumberStyles.Number, Culture, out var result))
					{
						SetToken(JsonToken.Float, result);
						return result;
					}
					throw JsonReaderException.smethod_1(this, "Could not convert string to decimal: {0}.".smethod_0(CultureInfo.InvariantCulture, Object_0));
				}
				case JsonToken.EndArray:
					return null;
				default:
					throw JsonReaderException.smethod_1(this, "Error reading decimal. Unexpected token: {0}.".smethod_0(CultureInfo.InvariantCulture, jsonToken));
				case JsonToken.Integer:
				case JsonToken.Float:
					if (!(Object_0 is decimal))
					{
						SetToken(JsonToken.Float, Convert.ToDecimal(Object_0, CultureInfo.InvariantCulture));
					}
					return (decimal)Object_0;
				}
			}
			SetToken(JsonToken.None);
			return null;
		}

		internal int? method_7()
		{
			enum14_0 = Enum14.ReadAsInt32;
			while (Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E())
			{
				switch (JsonToken_0)
				{
				case JsonToken.Comment:
					break;
				case JsonToken.Null:
					return null;
				case JsonToken.String:
				{
					string text = (string)Object_0;
					if (string.IsNullOrEmpty(text))
					{
						SetToken(JsonToken.Null);
						return null;
					}
					if (int.TryParse(text, NumberStyles.Integer, Culture, out var result))
					{
						SetToken(JsonToken.Integer, result);
						return result;
					}
					throw JsonReaderException.smethod_1(this, "Could not convert string to integer: {0}.".smethod_0(CultureInfo.InvariantCulture, Object_0));
				}
				case JsonToken.EndArray:
					return null;
				default:
					throw JsonReaderException.smethod_1(this, "Error reading integer. Unexpected token: {0}.".smethod_0(CultureInfo.InvariantCulture, JsonToken_0));
				case JsonToken.Integer:
				case JsonToken.Float:
					if (!(Object_0 is int))
					{
						SetToken(JsonToken.Integer, Convert.ToInt32(Object_0, CultureInfo.InvariantCulture));
					}
					return (int)Object_0;
				}
			}
			SetToken(JsonToken.None);
			return null;
		}

		internal string method_8()
		{
			enum14_0 = Enum14.ReadAsString;
			while (Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E())
			{
				JsonToken jsonToken = JsonToken_0;
				switch (jsonToken)
				{
				case JsonToken.Comment:
					continue;
				case JsonToken.String:
					return (string)Object_0;
				case JsonToken.Null:
					return null;
				}
				if (smethod_0(jsonToken) && Object_0 != null)
				{
					string text = ((!(Object_0 is IFormattable)) ? Object_0.ToString() : ((IFormattable)Object_0).ToString(null, Culture));
					SetToken(JsonToken.String, text);
					return text;
				}
				if (jsonToken != JsonToken.EndArray)
				{
					throw JsonReaderException.smethod_1(this, "Error reading string. Unexpected token: {0}.".smethod_0(CultureInfo.InvariantCulture, jsonToken));
				}
				return null;
			}
			SetToken(JsonToken.None);
			return null;
		}

		internal DateTime? method_9()
		{
			enum14_0 = Enum14.ReadAsDateTime;
			do
			{
				if (!Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E())
				{
					SetToken(JsonToken.None);
					return null;
				}
			}
			while (JsonToken_0 == JsonToken.Comment);
			if (JsonToken_0 == JsonToken.Date)
			{
				return (DateTime)Object_0;
			}
			if (JsonToken_0 == JsonToken.Null)
			{
				return null;
			}
			if (JsonToken_0 == JsonToken.String)
			{
				string text = (string)Object_0;
				if (string.IsNullOrEmpty(text))
				{
					SetToken(JsonToken.Null);
					return null;
				}
				if (DateTime.TryParse(text, Culture, DateTimeStyles.RoundtripKind, out var result))
				{
					result = Class185.smethod_2(result, DateTimeZoneHandling);
					SetToken(JsonToken.Date, result);
					return result;
				}
				throw JsonReaderException.smethod_1(this, "Could not convert string to DateTime: {0}.".smethod_0(CultureInfo.InvariantCulture, Object_0));
			}
			if (JsonToken_0 != JsonToken.EndArray)
			{
				throw JsonReaderException.smethod_1(this, "Error reading date. Unexpected token: {0}.".smethod_0(CultureInfo.InvariantCulture, JsonToken_0));
			}
			return null;
		}

		private bool method_10()
		{
			enum14_0 = Enum14.Read;
			if (JsonToken_0 == JsonToken.StartObject)
			{
				if (!Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E())
				{
					throw JsonReaderException.smethod_1(this, "Unexpected end when reading bytes.");
				}
				if (Object_0.ToString() == "$type")
				{
					Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E();
					if (Object_0 != null && Object_0.ToString().StartsWith("System.Byte[]"))
					{
						Newtonsoft_002EJson_002EJsonReader_002E_202E_206F_206A_206A_202D_202B_206A_202E_206F_206F_200B_200B_200F_206D_200F_206F_200C_200E_202A_202E_202A_206C_202B_200C_202A_206E_200C_202C_200D_200E_202D_200C_206D_200F_202B_206A_206B_200D_206C_202D_202E();
						if (Object_0.ToString() == "$value")
						{
							return true;
						}
					}
				}
				throw JsonReaderException.smethod_1(this, "Error reading bytes. Unexpected token: {0}.".smethod_0(CultureInfo.InvariantCulture, JsonToken.StartObject));
			}
			return false;
		}

		public void Skip()
		{
			if (JsonToken_0 == JsonToken.PropertyName)
			{
				Read();
			}
			if (smethod_1(JsonToken_0))
			{
				int int32_ = Int32_0;
				while (Read() && int32_ < Int32_0)
				{
				}
			}
		}

		protected void SetToken(JsonToken newToken)
		{
			SetToken(newToken, null);
		}

		protected void SetToken(JsonToken newToken, object value)
		{
			jsonToken_0 = newToken;
			object_0 = value;
			switch (newToken)
			{
			case JsonToken.StartObject:
				state_0 = State.ObjectStart;
				method_1(Enum12.Object);
				break;
			case JsonToken.StartArray:
				state_0 = State.ArrayStart;
				method_1(Enum12.Array);
				break;
			case JsonToken.StartConstructor:
				state_0 = State.ConstructorStart;
				method_1(Enum12.Constructor);
				break;
			case JsonToken.PropertyName:
				state_0 = State.Property;
				struct25_0.string_0 = (string)value;
				break;
			case JsonToken.EndObject:
				method_12(JsonToken.EndObject);
				break;
			case JsonToken.EndArray:
				method_12(JsonToken.EndArray);
				break;
			case JsonToken.EndConstructor:
				method_12(JsonToken.EndConstructor);
				break;
			case JsonToken.Raw:
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				state_0 = ((method_3() != 0) ? State.PostValue : State.Finished);
				method_11();
				break;
			case JsonToken.Comment:
				break;
			}
		}

		private void method_11()
		{
			if (struct25_0.bool_0)
			{
				struct25_0.int_0++;
			}
		}

		private void method_12(JsonToken jsonToken_1)
		{
			Enum12 @enum = method_2();
			if (method_13(jsonToken_1) != @enum)
			{
				throw JsonReaderException.smethod_1(this, "JsonToken {0} is not valid for closing JsonType {1}.".smethod_1(CultureInfo.InvariantCulture, jsonToken_1, @enum));
			}
			state_0 = ((method_3() != 0) ? State.PostValue : State.Finished);
		}

		protected void SetStateBasedOnCurrent()
		{
			Enum12 @enum = method_3();
			switch (@enum)
			{
			default:
				throw JsonReaderException.smethod_1(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".smethod_0(CultureInfo.InvariantCulture, @enum));
			case Enum12.None:
				state_0 = State.Finished;
				break;
			case Enum12.Object:
				state_0 = State.Object;
				break;
			case Enum12.Array:
				state_0 = State.Array;
				break;
			case Enum12.Constructor:
				state_0 = State.Constructor;
				break;
			}
		}

		internal static bool smethod_0(JsonToken jsonToken_1)
		{
			switch (jsonToken_1)
			{
			default:
				return false;
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				return true;
			}
		}

		internal static bool smethod_1(JsonToken jsonToken_1)
		{
			switch (jsonToken_1)
			{
			default:
				return false;
			case JsonToken.StartObject:
			case JsonToken.StartArray:
			case JsonToken.StartConstructor:
				return true;
			}
		}

		private Enum12 method_13(JsonToken jsonToken_1)
		{
			return jsonToken_1 switch
			{
				JsonToken.EndObject => Enum12.Object, 
				JsonToken.EndArray => Enum12.Array, 
				JsonToken.EndConstructor => Enum12.Constructor, 
				_ => throw JsonReaderException.smethod_1(this, "Not a valid close JsonToken: {0}".smethod_0(CultureInfo.InvariantCulture, jsonToken_1)), 
			};
		}

		void IDisposable.Dispose()
		{
			Dispose(disposing: true);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (state_0 != State.Closed && disposing)
			{
				Close();
			}
		}

		public virtual void Close()
		{
			state_0 = State.Closed;
			jsonToken_0 = JsonToken.None;
			object_0 = null;
		}
	}
}
